package vn.com.bookstore.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import vn.com.bookstore.dao.BookDao;
import vn.com.bookstore.dao.CustomerDao;
import vn.com.bookstore.dao.TransactionDao;
import vn.com.bookstore.domain.model.Book;
import vn.com.bookstore.domain.model.BookType;
import vn.com.bookstore.domain.model.Customer;
import vn.com.bookstore.domain.model.PagingInfo;
import vn.com.bookstore.domain.model.Publisher;
import vn.com.bookstore.domain.model.SearchResult;
import vn.com.bookstore.model.vo.AmountVO;
import vn.com.bookstore.model.vo.CardVO;
import vn.com.bookstore.model.vo.NganLuongModel;
import vn.com.bookstore.model.vo.TransactionVO;
import vn.com.bookstore.service.BooksOnlineService;
import vn.com.bookstore.service.CustomerService;
import vn.com.bookstore.utils.CardHelper;
import vn.com.bookstore.utils.DataHelper;
import vn.com.bookstore.utils.PaypalHelper;

@Controller
public class ManageBooksController {
	private static final Logger logger = LoggerFactory
			.getLogger(ManageBooksController.class);
	@Autowired
	private BooksOnlineService booksOnlineService;

	@Autowired
	private BookDao bookDao;

	@Autowired
	private CustomerDao customerDao;

	@Autowired
	private TransactionDao transactionDao;

	@Autowired
	private CustomerService customerService;

	@Value("${upload.ebooks.url.server}")
	public String URL_ROOT_FOLDER_UPLOAD_EBOOK;

	@Value("${hostname.url}")
	public String HOSTNAME_URL;

	@RequestMapping(value = "online/book-detail", method = RequestMethod.GET)
	public String viewDetail(Model model, @RequestParam("index") int id) {
		Book book = booksOnlineService.getBookById(id);
		Publisher publisher = booksOnlineService.getPublisherByid(book
				.getPublisherId());
		BookType bookType = booksOnlineService.getCategoryById(book
				.getBookTypeId());
		model.addAttribute("bookInfo", book);
		model.addAttribute("publisherInfo", publisher);
		model.addAttribute("categoryInfo", bookType);
		return "website/book/view-detail";
	}

	@RequestMapping(value = "online/ajax/getRelatedBook", method = RequestMethod.GET)
	public @ResponseBody
	ModelAndView getReleatedBook(@RequestParam("category") int categoryId,
			@RequestParam("index") int id) {
		ModelAndView model = new ModelAndView("website/book/related-book");
		List<Book> listBook = booksOnlineService.getRelatedBook(categoryId, id);
		model.addObject("listBook", listBook);
		return model;
	}

	@RequestMapping(value = "/online/book-list", method = RequestMethod.GET)
	public String getBookByCategory(@RequestParam("index") int categoryId,
			Model model) {
		PagingInfo pagingInfo = new PagingInfo(10, 1);
		SearchResult<Book> result = booksOnlineService.getBooksByBookTypeId(
				pagingInfo, categoryId);
		String bookTypeName = booksOnlineService.getCategoryById(categoryId)
				.getName();
		model.addAttribute("listBooks", result.getSearchResult());
		model.addAttribute("pagingInfo", result.getPagingInfo());
		model.addAttribute("bookTypeName", bookTypeName);
		model.addAttribute("categoryId", categoryId);
		return "website/book/searching-book-result";
	}

	@RequestMapping(value = "online/ajax/getMoreBooksByCategory", method = RequestMethod.POST)
	public ModelAndView getMoreBooksByCategory(
			@RequestParam("pageIndex") int pageIndex,
			@RequestParam("categoryId") int categoryId) {
		ModelAndView model = new ModelAndView("website/book/ajax-view-more");
		PagingInfo pagingInfo = new PagingInfo(10, pageIndex);
		SearchResult<Book> result = booksOnlineService.getBooksByBookTypeId(
				pagingInfo, categoryId);
		model.addObject("listBooks", result.getSearchResult());
		model.addObject("pagingInfo", result.getPagingInfo());
		model.addObject("categoryId", categoryId);
		return model;
	}

	@RequestMapping(value = "online/ajax/check-valid-amount", method = RequestMethod.POST)
	public @ResponseBody AmountVO checkValidAmountNganLuong(@RequestParam("bookId") Integer bookId) {
		AmountVO amountVO = new AmountVO();
		Book book = bookDao.getBookById(bookId);
		SecurityContext context = SecurityContextHolder.getContext();
		String username = context.getAuthentication().getName();
		Customer customer = customerService.getCustomerByUsername(username);
		
		if (book == null || customer == null || book.getPrice() > customer.getPointCart()) {
			amountVO.setCanBuyBook(false);
		}else{
			amountVO.setCanBuyBook(true);
		}
		if(customer != null){
			amountVO.setMoney(customer.getPointCart());
		}
		System.out.println("amountVO: "+amountVO.getMoney());
		return amountVO;
	}

	@RequestMapping(value = "/online/buy-books", method = RequestMethod.GET)
	public String openPayment(Model model, @RequestParam("index") Integer bookId) {
		Book book = bookDao.getBookById(bookId);
		Publisher publisher = booksOnlineService.getPublisherByid(book.getPublisherId());
		model.addAttribute("bookInfo", book);
		model.addAttribute("publisherInfo", publisher);
		return "website/payment/payment";
	}

	@RequestMapping(value = "/online/mobicard", method = RequestMethod.GET)
	public String mobicard(Model model) {
		String message = "";

		CardHelper cardHelper = new CardHelper();

		// ma the : 1825275650681
		// So serri: 80959912725
		// Loai the : VMS: MobiFone card, VNP: VinaPhone card, VIETTEL: Viettel
		// Orderid hoac customer name hoac customer account: NHIT
		cardHelper.checkout("1825275650681", "80959912725", "VIETTEL", "NHIT");
		CardVO resultCard = cardHelper.getResultCard();
		if (resultCard.getErrorCode().equals(CardHelper.CODE_SUCCESS)) {
			message = cardHelper.getErrorMessage() + ", mệnh giá thẻ = "
					+ resultCard.getCardAmount() + ", transaction amount = "
					+ resultCard.getTransactionAmount() + ", transaction id = "
					+ resultCard.getTransactionId();
		} else {
			message = cardHelper.getErrorMessage();
		}
		model.addAttribute("message", message);
		return "website/home/mobi-card";
	}
	@RequestMapping(value = "/online/ajax/top-up-ngan-luong", method = RequestMethod.POST)
	public @ResponseBody NganLuongModel topUpNganLuong(Model model,
			@RequestParam("cardCode") String cardCode, @RequestParam("seriCardNumber") String seriCardNumber,
			@RequestParam("cardType") Integer cardType) {
		NganLuongModel nlModel = new NganLuongModel();
		final Map<Integer, String> CARDTYPE= new HashMap<Integer, String>();
		CARDTYPE.put(1, "VIETTEL");
		CARDTYPE.put(2, "VNP");
		CARDTYPE.put(3, "VMS");
		SecurityContext context = SecurityContextHolder.getContext();
		String username = context.getAuthentication().getName();
		String message = "";
		CardHelper cardHelper = new CardHelper();
		String typeOfCard = CARDTYPE.get(cardType);
		// ma the : 1825275650681
		// So serri: 80959912725
		// Loai the : VMS: MobiFone card, VNP: VinaPhone card, VIETTEL: Viettel
		// Orderid hoac customer name hoac customer account: NHIT
		cardHelper.checkout(cardCode, seriCardNumber, typeOfCard, username);
		CardVO resultCard = cardHelper.getResultCard();
		if (resultCard.getErrorCode().equals(CardHelper.CODE_SUCCESS)) {
			nlModel.setHasError(false);
			message = cardHelper.getErrorMessage() + ", mệnh giá thẻ = "
					+ resultCard.getCardAmount() + ", transaction amount = "
					+ resultCard.getTransactionAmount() + ", transaction id = "
					+ resultCard.getTransactionId();
			nlModel.setMessage(message);
			//update amount of customer
			String usernameofCustomer  = resultCard.getRefCode();
			Customer customer = customerService.getCustomerByUsername(usernameofCustomer);
			customer.setPointCart(customer.getPointCart() + resultCard.getCardAmount());
			customerService.updateAmountOfCustomer(customer);
		} else {
			nlModel.setHasError(true);
			message = cardHelper.getErrorMessage();
		}
		nlModel.setMessage(message);
		return nlModel;
	}

	@SuppressWarnings({ "rawtypes", "unused" })
	@RequestMapping(value = "/online/payment", method = RequestMethod.GET)
	public String payment(Model model, HttpServletRequest request,
			HttpServletResponse response, @RequestParam("id") int id) {
		/*
		 * Book book = new Book(); book.setId(1); book.setName("Hoc Payment");
		 * book.setShortDescription("Huong dan payment"); book.setPrice(100);
		 */

		Book book = bookDao.getBookById(id);

		String returnUrl = "http://pavibook.vn"
				+ "/book-store/online/download?id=" + id;
		String cancelUrl = HOSTNAME_URL + "/book-store/online/home";

		PaypalHelper paypalHelper = new PaypalHelper();
		HashMap nvp = paypalHelper.CallShortcutExpressCheckout(book, returnUrl,
				cancelUrl);
		String ErrorCode = StringUtils.EMPTY;
		String ErrorShortMsg = StringUtils.EMPTY;
		String ErrorLongMsg = StringUtils.EMPTY;
		String ErrorSeverityCode = StringUtils.EMPTY;
		String strAck = "";
		if (nvp != null) {
			strAck = nvp.get("ACK").toString();
			if (strAck != null && strAck.equalsIgnoreCase("Success")) {
				model.addAttribute("tokenPaypal", nvp.get("TOKEN").toString());
				HttpSession session = request.getSession();
				session.setAttribute("token", nvp.get("TOKEN").toString());
				String tokenSession = (String) request.getSession()
						.getAttribute("token");
				// ' Redirect to paypal.com
				try {
					String s = paypalHelper.getPAYPAL_URL()
							+ nvp.get("TOKEN").toString();
					response.sendRedirect(paypalHelper.getPAYPAL_URL()
							+ nvp.get("TOKEN").toString());
				} catch (IOException e) {
					// logger.info(e.getMessage());
					// e.printStackTrace();
				}
			} else {
				// Display a user friendly Error on the page using any of the
				// following error information returned by PayPal

				ErrorCode = nvp.get("L_ERRORCODE0").toString();
				ErrorShortMsg = nvp.get("L_SHORTMESSAGE0").toString();
				ErrorLongMsg = nvp.get("L_LONGMESSAGE0").toString();
				ErrorSeverityCode = nvp.get("L_SEVERITYCODE0").toString();

				// logger.info("nvp: "+nvp.toString());
				// logger.info(ErrorCode + ":" + ErrorShortMsg + ":" +
				// ErrorLongMsg + ":" + ErrorSeverityCode);

				return ErrorLongMsg;

			}
		}

		return null;
	}

	@RequestMapping(value = "/online/searchBooks", method = RequestMethod.POST)
	public String searchBooks(Model model,
			@RequestParam("keyword") String keyword) {

		SearchResult<Book> result = booksOnlineService.getBooksBykeyword(
				new PagingInfo(10, 1), keyword);
		model.addAttribute("listBooks", result.getSearchResult());
		model.addAttribute("keyword", keyword);
		model.addAttribute("pagingInfo", result.getPagingInfo());
		return "website/book/books-list";
	}

	@RequestMapping(value = "/online/ajax/getMoreBooksByKeyword", method = RequestMethod.POST)
	public @ResponseBody
	ModelAndView getMoreBooksByKeyword(
			@RequestParam("pageIndex") int pageIndex,
			@RequestParam("keyword") String keyword) {
		ModelAndView model = new ModelAndView(
				"website/book/view-more-book-keyword");
		PagingInfo pagingInfo = new PagingInfo(10, pageIndex);
		SearchResult<Book> result = booksOnlineService.getBooksBykeyword(
				pagingInfo, keyword);
		model.addObject("listBooks", result.getSearchResult());
		model.addObject("keyword", keyword);
		model.addObject("pagingInfo", result.getPagingInfo());
		return model;
	}

	@RequestMapping(value = "/online/download", method = RequestMethod.GET)
	public void downloadFile(@RequestParam("id") int id,
			HttpServletResponse response, HttpServletRequest request) {
		String tokenRequest = request.getParameter("token");
		String tokenSession = (String) request.getSession().getAttribute(
				"token");
		if (tokenRequest != null) {
			if (tokenRequest.equals(tokenSession)) {
				request.getSession().removeAttribute("token");
				// get username
				SecurityContext context = SecurityContextHolder.getContext();
				String username = context.getAuthentication().getName();
				int customerId = customerDao.getCustomerIdByUsername(username);

				// save transaction
				TransactionVO transactionVO = new TransactionVO();
				transactionVO.setBookId(id);
				transactionVO.setCustomerId(customerId);
				Book book = booksOnlineService.getBookById(id);
				transactionVO.setTotalPrice(book.getPrice());
				transactionVO.setTransactionDate(new Date());
				transactionVO.setTransaction_type(DataHelper.TransactionType.PAYPAL.getCode());
				transactionDao.saveTransaction(transactionVO);

				// download
				String urlFile = book.getUrlPdfFile();
				String uri = URL_ROOT_FOLDER_UPLOAD_EBOOK + urlFile;
				String contentType = "application/pdf; charset=UTF-8";
				String fileType = ".pdf";
				String fileTypeCurrent = uri.substring(uri.lastIndexOf(".")+1);
				if(DataHelper.PdfFile.EPUB_FILE_TYPE.getCode().equalsIgnoreCase(fileTypeCurrent)){
					fileType = ".epub";
					contentType = "application/epub; charset=UTF-8";
				}
				try {
					File file = new File(uri);
					response.setContentType(contentType);
					response.setCharacterEncoding("UTF-8");
					response.setContentLength(new Long(file.length()).intValue());
					response.setHeader(
							"Content-Disposition",
							"attachment; filename="
									+ URLEncoder.encode(book.getName().replace(" ", "-"), "UTF-8")+ fileType);
					FileCopyUtils.copy(new FileInputStream(file),
							response.getOutputStream());
				} catch (Exception e) {
					logger.info("downloadFile : " + e.getMessage());
				}
			} else {
				logger.info("error Token ");
			}
		} else {
			logger.info("Token null ");
		}

	}

	@RequestMapping(value = "/online/nganluong/download", method = RequestMethod.GET)
	public void downloadFileWithNganLuong(@RequestParam("index") int id,
			HttpServletResponse response, HttpServletRequest request) {
		// get username
		SecurityContext context = SecurityContextHolder.getContext();
		String username = context.getAuthentication().getName();
		int customerId = customerDao.getCustomerIdByUsername(username);
		
		// save transaction
		TransactionVO transactionVO = new TransactionVO();
		transactionVO.setBookId(id);
		transactionVO.setCustomerId(customerId);
		Book book = booksOnlineService.getBookById(id);
		double priceBook = book.getPrice();
		if(book.getDiscount() > 0) {
			priceBook = priceBook - (priceBook*book.getDiscount()/100);
		}
		transactionVO.setTotalPrice(priceBook);
		//Subtract amount of customer
		Customer customer = customerService.getCustomerByUsername(username);
		if(customer.getPointCart() < priceBook) {
			return;
		}
		customer.setPointCart(customer.getPointCart() - priceBook);
		customerService.updateAmountOfCustomer(customer);
		
		transactionVO.setTransactionDate(new Date());
		transactionVO.setTransaction_type(DataHelper.TransactionType.NGANLUONG.getCode());
		transactionDao.saveTransaction(transactionVO);
		
		// download
		String urlFile = book.getUrlPdfFile();
		String uri = URL_ROOT_FOLDER_UPLOAD_EBOOK + urlFile;
		String contentType = "application/pdf; charset=UTF-8";
		String fileType = ".pdf";
		String fileTypeCurrent = uri.substring(uri.lastIndexOf(".")+1);
		if(DataHelper.PdfFile.EPUB_FILE_TYPE.getCode().equalsIgnoreCase(fileTypeCurrent)){
			fileType = ".epub";
			contentType = "application/epub; charset=UTF-8";
		}
		try {
			File file = new File(uri);
			response.setContentType(contentType);
			response.setCharacterEncoding("UTF-8");
			response.setContentLength(new Long(file.length()).intValue());
			response.setHeader("Content-Disposition", "attachment; filename="
					+ URLEncoder.encode(book.getName().replace(" ", "-"), "UTF-8") + fileType);
			FileCopyUtils.copy(new FileInputStream(file),
					response.getOutputStream());
		} catch (IOException e) {
			logger.info("downloadFile : " + e.getMessage());
		}
	}
}
